package com.tsd.jwt;

import com.tsd.core.config.Config;
import com.tsd.core.constants.JwtConstants;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.vo.HlpException;
import com.tsd.system.entity.SysUserExt;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

/**
 * @Description:
 * @Author Hillpool
 * @Date 2019/3/11 16:06
 * @Modefied By:
 */
public class JwtHelper {

    private static final String ENCODING_AES_KEY;
    private static final Integer TOKEN_EXPIRED_SECONDS;
    private static final Long TOKEN_EXPIRED_MS;

    static {
        ENCODING_AES_KEY = Config.getParameterValue("encodingAESKey");
        Integer integer;
        String tokenExpiredSeconds = Config.getParameterValue("tokenExpiredSeconds");
        if (!HlpUtils.isEmpty(tokenExpiredSeconds)) {
            try {
                integer = Integer.parseInt(tokenExpiredSeconds);
            } catch (Exception e) {
                integer = 7200;
            }
        } else {
            integer = 7200;
        }
        TOKEN_EXPIRED_SECONDS = integer;
        TOKEN_EXPIRED_MS = integer.longValue() * 1000;
    }

    public static String createJWT(String type, SysUserExt opUser) throws HlpException {
        if (HlpUtils.isEmpty(ENCODING_AES_KEY)) {
            throw new HlpException("token加密密钥不能为空");
        }
        return createJWT(type, opUser, TOKEN_EXPIRED_MS, ENCODING_AES_KEY);
    }

    public static String createJWT(String type, SysUserExt opUser, long expired) {
        return createJWT(type, opUser, expired, ENCODING_AES_KEY);
    }

    public static String createJWT(String type, SysUserExt opUser, long TTLMillis, String base64Security) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        //生成签名密钥
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(base64Security);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        //添加构成JWT的参数
        JwtBuilder builder = Jwts.builder();
        builder.setHeaderParam("typ", "JWT");
        builder.claim(JwtConstants.CLAIM_NAME_TYPE, type);
        builder.claim(JwtConstants.CLAIM_NAME_ID, opUser.getId());
        builder.claim(JwtConstants.CLAIM_NAME_SID, opUser.getSid());
        builder.claim(JwtConstants.CLAIM_NAME_LOGIN_ID, opUser.getLogin_id());
        builder.claim(JwtConstants.CLAIM_NAME_USER_NAME, opUser.getName());
        builder.claim(JwtConstants.CLAIM_NAME_GROUP_SID, opUser.getGroup_sid());
        if (!HlpUtils.isEmpty(opUser.getPerson_group_sid())) {
            builder.claim(JwtConstants.CLAIM_NAME_GROUP_SID, opUser.getPerson_group_sid());
        }
        builder.claim(JwtConstants.CLAIM_NAME_GROUP_PERSON_SID, opUser.getGroup_person_sid());
        builder.claim(JwtConstants.TYPE_CLIENT_OPERATOR, opUser.getClient_sid());
        builder.claim(JwtConstants.CLAIM_NAME_OPEN_ID, opUser.getOpen_id());
        builder.claim(JwtConstants.CLAIM_NAME_CLIENT_AUTH_MODE, opUser.getClient_auth_mode());
        builder.claim(JwtConstants.CLAIM_NAME_CLIENT_AUTH_SETTING, opUser.getClient_auth_setting());
        builder.claim(JwtConstants.CLAIM_NAME_DEVICE_TYPR, opUser.getDevice_type());

        builder.signWith(signatureAlgorithm, signingKey);
        //添加Token过期时间
        if (TTLMillis >= 0) {
            long expMillis = nowMillis + TTLMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp).setNotBefore(now);
        }
        //生成JWT
        return builder.compact();
    }
}
